package org.colafries.admin.service.impl.index;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.collections4.CollectionUtils;
import org.colafries.admin.entity.domain.index.LogicFactTableField;
import org.colafries.admin.entity.vo.index.LogicFactTblFieldReqVO;
import org.colafries.admin.exceptions.ServiceException;
import org.colafries.admin.exceptions.enums.ErrorCodeEnum;
import org.colafries.admin.mapper.index.LogicFactTableFieldMapper;
import org.colafries.admin.service.index.ILogicFactTableFieldService;
import org.colafries.common.enums.Flag;
import org.colafries.common.snowflake.SnowFlake;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * <p>
 * 逻辑事实表字段明细表 服务实现类
 * </p>
 *
 * @author Ann
 * @since 2024-06-03
 */
@Service
public class ILogicFactTableFieldServiceImpl extends ServiceImpl<LogicFactTableFieldMapper, LogicFactTableField> implements ILogicFactTableFieldService {

    @Autowired
    LogicFactTableFieldMapper logicFactTableFieldMapper;

    @Override
    public int add(LogicFactTblFieldReqVO reqVO) {
        if (CollectionUtils.isEmpty(reqVO.getLogicTblFieldList())) {
            log.warn("参数异常：逻辑表字段为空");
            throw new ServiceException(ErrorCodeEnum.GL999999, "参数异常：逻辑表字段为空");
        }
        List<LogicFactTableField> logicFactTableFieldList = reqVO.getLogicTblFieldList().stream().map(logicTableFieldVO -> {
            //判断是否同名字段
            if (Flag.YES == FieldExistsFlag(logicTableFieldVO.getField())) {
                throw new ServiceException(ErrorCodeEnum.GL999999, "存在同名字段");
            }
            //新增字段
            Long code = SnowFlake.nextId();
            return LogicFactTableField.builder()
                    .code(code)
                    .logicTableCode(reqVO.getLogicTableCode())
                    .field(logicTableFieldVO.getField())
                    .alias(logicTableFieldVO.getAlias())
                    .dataType(logicTableFieldVO.getDataType())
                    .expression(logicTableFieldVO.getExpression())
                    .logicFieldType(logicTableFieldVO.getLogicFieldType())
                    .createUser(reqVO.getCreateUser())
                    .updateUser(reqVO.getUpdateUser())
                    .build();
        }).collect(Collectors.toList());
        this.saveBatch(logicFactTableFieldList);
        return logicFactTableFieldList.size();
    }

    @Override
    public int delete(LogicFactTblFieldReqVO reqVO) {
        if (CollectionUtils.isEmpty(reqVO.getLogicTblFieldList())) {
            throw new ServiceException(ErrorCodeEnum.GL999999, "参数异常：逻辑表字段为空");
        }
        List<Long> reqCodeList = reqVO.getLogicTblFieldList().stream()
                .map(LogicFactTblFieldReqVO.LogicTableFieldVO::getCode).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(reqCodeList)) {
            throw new ServiceException(ErrorCodeEnum.GL999999, "参数异常：逻辑表字段为空");
        }

        LambdaQueryWrapper<LogicFactTableField> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(LogicFactTableField::getLogicTableCode,reqVO.getLogicTableCode())
                .in(LogicFactTableField::getCode, reqCodeList);

        return logicFactTableFieldMapper.delete(queryWrapper);
    }

    /**
     * 判断是否存在同名字段
     *
     * @param field
     * @return org.colafries.common.enums.Flag
     * @Author anning
     * @Date 2024/6/6
     */
    private Flag FieldExistsFlag(String field) {
        Integer cnt = logicFactTableFieldMapper.selectCount(
                Wrappers.<LogicFactTableField>lambdaQuery().eq(LogicFactTableField::getField, field)
        );
        if (cnt > 0) {
            return Flag.YES;
        }
        return Flag.NO;
    }

    @Override
    public int update(LogicFactTblFieldReqVO reqVO) {
        AtomicInteger updateCount = new AtomicInteger(0);
        if (CollectionUtils.isEmpty(reqVO.getLogicTblFieldList())) {
            throw new ServiceException(ErrorCodeEnum.GL999999, "参数异常：逻辑表字段为空");
        }
        if (reqVO.getLogicTblFieldList().size() > 1) {
            throw new ServiceException(ErrorCodeEnum.GL999999, "参数异常：只能修改一个字段");
        }
        Optional.of(reqVO.getLogicTblFieldList())
                .map(list -> list.get(0))
                .ifPresent(field -> {
                    Long code = field.getCode();
                    LogicFactTableField newField = LogicFactTableField.builder()
                            .code(code)
                            .logicTableCode(reqVO.getLogicTableCode())
                            .field(field.getField())
                            .alias(field.getAlias())
                            .dataType(field.getDataType())
                            .expression(field.getExpression())
                            .logicFieldType(field.getLogicFieldType())
                            .updateUser(reqVO.getUpdateUser())
                            .build();
                    int cnt = logicFactTableFieldMapper.update(newField,
                            Wrappers.<LogicFactTableField>lambdaUpdate().eq(LogicFactTableField::getCode, code)
                    );
                    updateCount.set(cnt);
                });
        return updateCount.get();
    }

    @Override
    public List<LogicFactTableField> listAll(LogicFactTblFieldReqVO reqVO) {
        LambdaQueryWrapper<LogicFactTableField> queryWrapper = new LambdaQueryWrapper<>();
        if (null != reqVO.getLogicTableCode()) {
            queryWrapper.eq(LogicFactTableField::getLogicTableCode, reqVO.getLogicTableCode());
        }
        return logicFactTableFieldMapper.selectList(queryWrapper);
    }

    @Override
    public IPage<LogicFactTableField> pageList(LogicFactTblFieldReqVO reqVO) {
        LambdaQueryWrapper<LogicFactTableField> queryWrapper = new LambdaQueryWrapper<>();
        if (null != reqVO.getLogicTableCode()) {
            queryWrapper.eq(LogicFactTableField::getLogicTableCode, reqVO.getLogicTableCode());
        }
        // TODO 其他筛选条件 ... ...
        Page<LogicFactTableField> page = new Page<>(reqVO.getCurrent(), reqVO.getSize());
        IPage<LogicFactTableField> result = logicFactTableFieldMapper.selectPage(page, queryWrapper);

        if (result.getTotal() > 0 && result.getRecords().isEmpty()) {
            long current = result.getPages();
            page = new Page<>((int) current, reqVO.getSize());
            result = logicFactTableFieldMapper.selectPage(page, queryWrapper);
        }
        return result;
    }

    @Override
    public LogicFactTableField queryByCode(Long logicTableFieldCode) {
        return baseMapper.selectOne(
                Wrappers.<LogicFactTableField>lambdaQuery().eq(LogicFactTableField::getCode,logicTableFieldCode)
        );
    }

    /**
     * 根据逻辑表code查询逻辑表字段
     * @param logicTableCode
     * @return java.util.List<org.colafries.admin.entity.domain.index.LogicFactTableField>
     * @Author anning
     * @Date 2024/7/5
     */
    @Override
    public List<LogicFactTableField> listByTableCode(Long logicTableCode) {
        return baseMapper.selectList(
                Wrappers.<LogicFactTableField>lambdaQuery().eq(LogicFactTableField::getLogicTableCode,logicTableCode)
        );
    }

}
